package com.tdd.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @author xiaoxiyuan
 * @description 服务端
 * @date 2020-06-11 15:13:00
 */
public class MyServer {

    public static void main(String[] args) throws Exception{
        //创建两个NIO线程组
        //bossGroup负责接收客户端的连接
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        //workerGroup负责网络读写
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            //创建服务端启动器，ServerBootstrap是NIO服务端的辅助启动类，可以降低服务端的开发难度
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            // 链式调用group方法，传入bossGroup和workerGroup，
            // 将bossGroup赋值给parentGroup属性，将workerGroup赋值给childGroup
            serverBootstrap.group(bossGroup,workerGroup)
                    //channel方法传入NioServerSocketChannel的class对象，根据这个传入的class创建Channel对象
                    .channel(NioServerSocketChannel.class)
                    //childHandler方法传入一个handler，这个handler将会在每个客户端连接的时候被调用，即供SocketChannel使用
                    .childHandler(new MyServerInitializer());

            //serverBootstrap启动类配置完成之后,调用bind绑定监听端口，sync同步等待绑定操作完成
            // 绑定成功之后返回ChannelFuture类似JDK中的Future，用于异步操作回调通知
            ChannelFuture channelFuture = serverBootstrap.bind(8000).sync();
            System.out.println("服务端启动成功！");
            //等待服务端链路关闭之后main函数退出
            channelFuture.channel().closeFuture().sync();

        }finally {
            //优雅的关闭两个线程池，释放线程资源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }
}
